<?php
namespace app\im\controller;
use app\im\controller\MessageHander;
//use think\swoole\Websocket as websocket;
use Swoole\Http\Server as HttpServer;
use Swoole\Websocket\Server as WebsocketServer;
use think\App;
use think\Route;
use think\swoole\command\Server as ServerCommand;
use think\swoole\facade\Server;
use think\swoole\websocket\socketio\Controller;
use think\swoole\websocket\socketio\Middleware;
use think\facade\Config;


//推送服务器
class PushServer extends \think\Service
{
	private static $instance;
	private static $server;
	private $config;
	//处理消息对象
	private $messageHandler;
	
	protected $isWebsocket = false;
	
	public function __construct()
	{
//		parent::__construct();
		//创建websocket对象
//		self::$server = new swoole_websocket_server("0.0.0.0", 8006);
//		self::$server = $server::$server;
//		self::$server = new websocket("0.0.0.0", 8006);
		$this->init();
		$this->register();
		//设置
//		self::initServer();
		//注册事件
		//连接客户端
		self::$server->on("open" ,[$this , "onOpen"]);
		//发送消息
		self::$server->on('message' ,[$this ,'onMessage']);
		//关闭连接
		self::$server->on('close' ,[$this ,'onClose']);
		//异步
		self::$server->on('task' ,[$this ,'onTask']);
		//启动时运行
		self::$server->on('workerStart' ,[$this ,'onWorkerStart']);
		
	}
	//获取
	public static function getInstance() 
	{
		if(!self::$instance instanceof self)
		{
			self::$instance = new self();
		}
		return self::$instance;	
	}
	
	protected function init()
    {
        $this->config = Config::get('swoole');
    }
	
	public function register()
    {
        $this->isWebsocket = Config::get('swoole.websocket.enabled');
		$this->createSwooleServer();
    }

    public function boot(Route $route)
    {
        $this->commands(ServerCommand::class);
        if ($this->isWebsocket) {
            $route->group(function () use ($route) {
                $route->get('socket.io/', '@upgrade');
                $route->post('socket.io/', '@reject');
            })->prefix(Controller::class)->middleware(Middleware::class);
        }
    }

    /**
     * Create swoole server.
     */
    protected function createSwooleServer()
    {
        $server     = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
        $config     = $this->config;
        $host       = Config::get('swoole.server.host');
        $port       = Config::get('swoole.server.port');
        $socketType = Config::get('swoole.server.socket_type', SWOOLE_SOCK_TCP);
        $mode       = Config::get('swoole.server.mode', SWOOLE_PROCESS);
        self::$server = new $server($host, $port, $mode, $socketType);
        $options = Config::get('swoole.server.options');
        self::$server->set($options);
    }
	
	
	//启动服务器
	public function start() 
	{
		self::$server->start();
	}
	
	//客户端连接上后执行的方法
	public function onOpen($server ,$req)
	{
		self::$server->push($req->fd ,json_encode(['action' => 'connect' ,'status' => true ,'data' => [] ,'message' => 'connect success.'] ,true));
	}
	
	//客户端连接上后执行的方法
	public function onMessage($server ,$frame)
	{
		self::$server->reload();//重新加载代码
		$data = json_decode($frame->data ,true);
		$result = null;
		if(method_exists($this->messageHandler, $data['action']))
		{
			$result = call_user_func([$this->messageHandler, $data['action']] ,self::$server ,$frame->fd ,$data);	
		}
	}
	//异步
	public function onTask($server ,$frame) 
	{
		
	}
	
	//关闭连接
	public function onClose($server ,$fd)
	{
		call_user_func([$this->messageHandler, 'logout'] ,$fd);	
	}
	//onWorkerStart
	public function onWorkerStart() 
	{
		// 加载框架里面的文件
		require __DIR__ . '/../../../vendor/autoload.php';
		$http = ( new App() )->http;
		$response = $http->run();
		$this->messageHandler = new MessageHandlerV2();
	}
	//发送消息
	public function sendMessage($fd ,$data){
		self::$server->push($fd ,$data);
	}
}
